package jp.sourceforge.akjrcp.psp;

import java.io.File;
import java.io.IOException;

import jp.sourceforge.akjrcp.akj_betas.Messages;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegGenericParameters;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegOptions;
import jp.sourceforge.akjrcp.ui.GenericParameters;
import jp.sourceforge.akjrcp.ui.GenericParametersEventListener;
import jp.sourceforge.akjrcp.ui.GenericParametersFFMpegPreference;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.PlatformUI;

public class PSPMovieSettingEditor extends FieldEditor {

	private Button upButton, downButton, topButton, bottomButton;

	private Button exportButton;
	// todo add new edit remove
	private PSPMovieSettingTableViewer table;



	private Label label;

	private Composite menus;


	public PSPMovieSettingEditor(String key, String description,
			Composite parent) {
		super(key, description, parent);

	}
	
	

	protected void adjustForNumColumns(int numColumns) {
		// adjust
		//log.infoadjust:" + numColumns);
	}

	private Table getTable(Composite parent) {
		if (table == null) {
			
			table = new PSPMovieSettingTableViewer(parent);
			
		}
		return table.getTable();
	}

	public class FixComposite extends Composite{

		public FixComposite(Composite parent, int style) {
			super(parent, style);
			
		}
		
		public Point computeSize(int wHint,
                int hHint,
                boolean changed){
			
			return new Point(480,300);
		}
		
	}
	protected void doFillIntoGrid(Composite parent, int numColumns) {
		Label label = getLabel(parent);
		GridData ld = new GridData();
		ld.horizontalSpan = numColumns;
		label.setLayoutData(ld);
		
		Composite fill=new Composite(parent,SWT.NONE);
		GridData gd1 = new GridData(GridData.FILL_HORIZONTAL);
		gd1.horizontalSpan = numColumns;//fill
		fill.setLayoutData(gd1);
		fill.setLayout(new GridLayout(2,false));
		
		FixComposite composite=new FixComposite(fill,SWT.NULL);
		composite.setLayout(new FillLayout());
		
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		
		gd.grabExcessVerticalSpace=true;
		gd.grabExcessHorizontalSpace=true;
		//log.info("col:" + numColumns);
		//gd.horizontalSpan = numColumns - 1;
		//gd.minimumHeight = 300;
		//gd.minimumWidth = 400;
		composite.setLayoutData(gd); // should re-set new gridData
		
		Table table = getTable(composite);
		

		Composite menus = getMenus(fill);
		menus.setLayoutData(new GridData());// should re-set new gridData

	}

	private Label getLabel(Composite parent) {
		if (label == null) {
			label = new Label(parent, SWT.NULL);
			label.setText(getLabelText());

		}
		return label;
	}

	private Composite getMenus(Composite parent) {
		if (menus == null) {
			menus = new Composite(parent, SWT.NULL);

			menus.setLayout(new GridLayout());

			topButton = createButton(menus, Messages
					.getString("pspmoviesetting.top"));
			upButton = createButton(menus, Messages
					.getString("pspmoviesetting.up"));
			downButton = createButton(menus, Messages
					.getString("pspmoviesetting.down"));
			bottomButton = createButton(menus, Messages
					.getString("pspmoviesetting.bottom"));
			
			exportButton =createButton(menus, Messages
					.getString("export"));

		}
		return menus;
	}

	public Button createButton(Composite p, String label) {
		Button bt = new Button(p, SWT.NULL);
		bt.setText(label);
		bt.addSelectionListener(new ButtonSelect());
		bt.setLayoutData(new GridData());
		return bt;
	}

	public class ButtonSelect implements SelectionListener {

		public void widgetSelected(SelectionEvent e) {
			//TODO
			int index=table.getTable().getSelectionIndex();
			if (e.widget == topButton) {
				PSPMovieSetting setting=(PSPMovieSetting) table.getMovieSettingList().get(index);
				table.getMovieSettingList().remove(setting);
				table.getMovieSettingList().add(0,setting);
				table.refresh();
				
			}else if (e.widget == upButton) {
				PSPMovieSetting setting=(PSPMovieSetting) table.getMovieSettingList().get(index);
				table.getMovieSettingList().remove(setting);
				table.getMovieSettingList().add(Math.max(0,index-1),setting);
				table.refresh();
				
			}else if (e.widget == downButton) {
				PSPMovieSetting setting=(PSPMovieSetting) table.getMovieSettingList().get(index);
				table.getMovieSettingList().remove(setting);
				table.getMovieSettingList().add(Math.min(table.getMovieSettingList().size(),index+1),setting);
				table.refresh();
				
			}else if (e.widget == bottomButton) {
				PSPMovieSetting setting=(PSPMovieSetting) table.getMovieSettingList().get(index);
				table.getMovieSettingList().remove(setting);
				table.getMovieSettingList().add(table.getMovieSettingList().size(),setting);
				table.refresh();
				
			}else if (e.widget == exportButton) {
				PSPMovieSetting[] settings=(PSPMovieSetting[]) table.getMovieSettingList().toArray(new PSPMovieSetting[0]);
				FileDialog dialog=new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),SWT.SAVE);
				dialog.setFilterExtensions(new String[]{"*.csv"});
				String path=dialog.open();
				if(path!=null){
					//GenericParameters infos[] = (GenericParameters[]) table.getGenericParameters().toArray(new GenericParameters[0]);
					
					String text=toGenericStoreString(settings);
					
					//String text=getPreferenceStore().getString(getPreferenceName());
					//text=StringUtils.replace(text, "\n", "\r\n");
					try {
						FileUtils.writeStringToFile(new File(path), text);
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				
			}  
			/*else if (e.widget == editButton) {
				int index = table.getTable().getSelectionIndex();
				FTPInfo info = (FTPInfo) movieSettingList.get(index);
				FTPInfoDialog dialog = new FTPInfoDialog(getPage().getShell());
				dialog.setFtpInfo(info);
				int bt = dialog.open();
				log.info.println(bt);
				if (bt == 0) {
					info.copyValue(dialog.getFtpInfo());

					table.refresh();
					saveStore();
				}

			} else if (e.widget == removeButton) {
				int index = table.getTable().getSelectionIndex();
				movieSettingList.remove(movieSettingList.get(index));
				table.refresh();
				saveStore();
			} else if (e.widget == table.getTable()) {
				// should support double click
			}*/
			
			saveStore();
		}

		public void widgetDefaultSelected(SelectionEvent e) {
			
		}

	}

	/*
	 * private String toStoreString(List list){ StringBuffer buffer=new
	 * StringBuffer(); FTPInfo infos[]=(FTPInfo[]) list.toArray(new FTPInfo[0]);
	 * log.info(infos.length); log.info(table.getInput());
	 * for (int i = 0; i < infos.length; i++) {
	 * buffer.append(toStoreString(infos[i])+"\n"); } return buffer.toString(); }
	 */



	protected void doLoad() {
		PSPMovieSetting[] settings = PSPMovieSettingTableViewer.toPSPMovieSettings(getPreferenceStore().getString(
				getPreferenceName()));
		for (int i = 0; i < settings.length; i++) {
			table.getMovieSettingList().add(settings[i]);
		}
		table.refresh();
	}

	protected void doLoadDefault() {
		// do nothing.
	}

	private void saveStore() {
		setPresentsDefaultValue(false);

		
		PSPMovieSetting infos[] = (PSPMovieSetting[]) table.getMovieSettingList().toArray(new PSPMovieSetting[0]);
		
		getPreferenceStore().setValue(getPreferenceName(),toStoreString(infos));
	}
	
	public static String toGenericStoreString(PSPMovieSetting[] settings){
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < settings.length; i++) {
			//settings[i].
			FFMpegGenericParameters parameters=new FFMpegGenericParameters();
			parameters.setName("PSP "+settings[i].getComment());
			
			if(settings[i].getVideoCodec()==PSPMovieSetting.XVID){
				parameters.setVideoCodec(FFMpegOptions.CODEC_VIDEO_XVID);
			}else{
				parameters.setVideoCodec(FFMpegOptions.CODEC_VIDEO_H264);
			}
			parameters.set(GenericParametersFFMpegPreference.MAX_FRAME_RATE, "30");
			parameters.setExtension(FFMpegOptions.EXTENSION_MP4);
			parameters.setFormat(FFMpegOptions.FORMAT_PSP);
			parameters.setAudioCodec(FFMpegOptions.CODEC_AUDIO_AAC);
			
			//flags
			parameters.setFlags(new String[]{FFMpegOptions.FLAGS_BITEXACT});//maybe need it.
			//coder
			parameters.setCoder(FFMpegOptions.CODER_1);
			
			parameters.setVideoSize(settings[i].getWidth(),settings[i].getHeight());
			parameters.setVideoBitrate(settings[i].getVideoBitrate());
			parameters.setAudioBitrate(settings[i].getAudioBitrate());
			parameters.setAudioChannel(settings[i].getAudioChannel());
			parameters.setAudioRate(settings[i].getAudioRate());
			
			
			if(settings[i].getVideoCodec()==PSPMovieSetting.H264){
				
				parameters.setLevel(FFMpegOptions.LEVEL_21);
			}else{
				//xvid need tag
				parameters.setVtag(FFMpegOptions.TAG_MP4VIDEO);
				
			}
			
			if(settings[i].getVideoSize().equals(PSPMovieSetting.SIZE_368x272)){
				parameters.setLevel(FFMpegOptions.LEVEL_30);
			}else if(settings[i].getVideoSize().equals(PSPMovieSetting.SIZE_720x480)){
				parameters.setLevel(FFMpegOptions.LEVEL_30);
			}else if(settings[i].getVideoSize().equals(PSPMovieSetting.SIZE_480x272)){
				parameters.setLevel(FFMpegOptions.LEVEL_30);
			}else if(settings[i].getVideoSize().equals(PSPMovieSetting.SIZE_352x480)){
				parameters.setLevel(FFMpegOptions.LEVEL_30);
			}
if(settings[i].getVideoCodec()==PSPMovieSetting.H264){
	if(settings[i].getVideoBitrate()>=PSPMovieSetting.BITRATE_768 && settings[i].getVideoBitrate()<PSPMovieSetting.BITRATE_1536){
		
		parameters.setMaxRate(FFMpegOptions.BITRATE_MAX_LEVEL21_4000);
		parameters.setBufSize(FFMpegOptions.BITRATE_MAX_LEVEL21_4000);
		
	}else if(settings[i].getVideoBitrate()>=PSPMovieSetting.BITRATE_1536){
		
		parameters.setMaxRate(FFMpegOptions.BITRATE_MAX_LEVEL30_10000);
		parameters.setBufSize(FFMpegOptions.BITRATE_MAX_LEVEL30_10000);
		
	}
				
			}
	
			
//hq setting
if(settings[i].isHighQuality()){
	parameters.set("refs", "3");
	parameters.set("loop", "1");
	parameters.set("deblockalpha", "0");
	parameters.set("deblockbeta", "0");
	parameters.set("partitions", "partp8x8+partb8x8");
	parameters.set("me", "umh");
	parameters.set("subq", "6");
	parameters.set("brdo", "1");
	parameters.set("me_range", "21");
	parameters.set("chroma", "1");
	parameters.set("slice", "2");
	parameters.set("g", "250");
	parameters.set("keyint_min", "25");
	parameters.set("sc_threshold", "40");
	parameters.set("rc_eq", "blurCplx^(1-qComp)");
	parameters.set("qcomp", "0.60");
	parameters.set("qmin", "7");
	parameters.set("qmax", "35");
	}
			
			buffer.append(GenericParameters.parametersToCsv(parameters) + "\r\n");
		}
		return buffer.toString();
	}

	
	public static String toStoreString(PSPMovieSetting[] settings){
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < settings.length; i++) {
			buffer.append(PSPMovieSettingTableViewer.toStoreString(settings[i]) + "\n");
		}
		return buffer.toString();
	}

	protected void doStore() {
		// do nothing. because automatic save
	}

	public int getNumberOfControls() {
		return 2;
	}

	

}
